package com.example.springboot_system.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.springboot_system.mapper.*;
import com.example.springboot_system.pojo.*;
import com.example.springboot_system.pojo.vo.ApplyRspVO;
import com.example.springboot_system.service.UserService;
import com.example.springboot_system.utils.GetIp;
import com.example.springboot_system.utils.IpAddress;
import com.example.springboot_system.utils.PhoneVerification;
import com.example.springboot_system.utils.ResponseResult;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import com.example.springboot_system.pojo.Role;
import org.springframework.web.bind.annotation.RequestParam;

@Service
public class UserSeviceImpl implements UserService {
    @Autowired(required = false)
    private UserMapper userMapper;
    @Autowired(required = false)
    private RoleMapper roleMapper;
    @Autowired(required = false)
    private UserRoleMapper userRoleMapper;
    @Autowired(required = false)
    private AnnounceMapper announceMapper;
    @Autowired(required = false)
    private LoginInfoMapper loginInfoMapper;

    private GetIp IpUtil;

    //登录
    @Override
    public ResponseResult doLogin(String email, String plainPassword, HttpSession session,
                                  HttpServletRequest request) throws UnknownHostException {
//        System.out.println("doLogin_email:"+email);
//        System.out.println("doLogin_plainPassword:"+plainPassword);
        if (email == null || email == "") {
            return new ResponseResult(201, "邮箱不能为空");
        }
        if (plainPassword == null || plainPassword == "") {
            return new ResponseResult(201, "密码不能为空");
        }


//        System.out.println("email："+email);
//        System.out.println("plainPassword："+plainPassword);
//        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("email",email);
//        /*queryWrapper.eq("plainPassword",plainPassword);*/
//
//        User user = userMapper.selectOne(queryWrapper);
//
//        /*List<User> userList =  userMapper.selectList(queryWrapper);*/
//        session.setAttribute("user",user);
//        System.out.println("user："+user);
//
//        return new ResponseResult(200,"登录成功");
        // 使用token 对登录数据进行封装， token 是一个全局变量
        UsernamePasswordToken token = new UsernamePasswordToken(email, plainPassword);
        // 获取当前用户subject
        Subject subject = SecurityUtils.getSubject();
        // 执行登录
        try {
            subject.login(token);
            QueryWrapper<User> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("email", email);
            /*queryWrapper.eq("plainPassword",plainPassword);*/
            User user = userMapper.selectOne(queryWrapper1);
            Integer emailStatus = user.getEmailStatus();
            if (!emailStatus.equals(1)) {
                return new ResponseResult(201, "用户审核不通过,请联系管理员");
            }
            /*List<User> userList =  userMapper.selectList(queryWrapper);*/
//            System.out.println("执行了session绑定 \n");
            session.setAttribute("user", user);
            session.setAttribute("username", user.getUsername());
            session.setAttribute("id", user.getId());
            //绑定用户的Uid
            QueryWrapper<Announce> queryWrapper = new QueryWrapper<>();
            List<Announce> announceList = announceMapper.selectList(queryWrapper);
            session.setAttribute("announceList", announceList);
            //获取用户的登录地址
            String v4IP = GetIp.getV4IP();
//        System.out.println(v4IP);
            String cityInfo = IpAddress.getCityInfo(v4IP);
            if(cityInfo==null){
                return new ResponseResult(205, "登录异常");
            }
            //封装成对象存进数组
            LoginInfo loginInfo = new LoginInfo();
            String suiji = (int) ((Math.random() * 9 + 1) * 100000) + "";
            loginInfo.setId(suiji);
            loginInfo.setUserId(user.getId());
            loginInfo.setLoginIp(v4IP);
            loginInfo.setLoginAddress(cityInfo);
            loginInfo.setCreateDatetime(new Date());
            loginInfo.setDescription(user.getEmail());
            int a = loginInfoMapper.insert(loginInfo);
//        System.out.println(a);
            return new ResponseResult(200, "登录成功");
        } catch (UnknownAccountException e) {
            return new ResponseResult(201, " UnknownAccountException e 邮箱不能为空");
        } catch (IncorrectCredentialsException e) {
            return new ResponseResult(201, "IncorrectCredentialsException e 密码不能为空");
        }

    }

    //电话号码验证登录
    @Override
    public ResponseResult doLoginByPhone(String phone, String code, HttpSession session) {
        if (phone == null || phone == "") {
            return new ResponseResult(201, "电话号码不能为空");
        }
        if (code == null || code == "") {
            return new ResponseResult(202, "验证码不能为空");
        }
        String phoneCode = (String) session.getAttribute("phoneCode");
//        System.out.println(phoneCode);
        if (!code.equals(phoneCode)) {
            return new ResponseResult(203, "验证码输入错误");
        }
//        System.out.println(phone);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", phone);
        User user = userMapper.selectOne(queryWrapper);
        if (user == null) {
            return new ResponseResult(204, "帐号可能已经被删除");
        }
        session.setAttribute("user", user);
        session.setAttribute("username", user.getUsername());
        session.setAttribute("id", user.getId());
        //绑定用户的Uid
        QueryWrapper<Announce> queryWrapper1 = new QueryWrapper<>();
        List<Announce> announceList = announceMapper.selectList(queryWrapper1);
        session.setAttribute("announceList", announceList);
        //获取用户的登录地址
        String v4IP = GetIp.getV4IP();
//        System.out.println(v4IP);
        String cityInfo = IpAddress.getCityInfo(v4IP);
        //封装成对象存进数组
        LoginInfo loginInfo = new LoginInfo();
        String suiji = (int) ((Math.random() * 9 + 1) * 100000) + "";
        loginInfo.setId(suiji);
        loginInfo.setUserId(user.getId());
        loginInfo.setLoginIp(v4IP);
        loginInfo.setLoginAddress(cityInfo);
        loginInfo.setCreateDatetime(new Date());
        loginInfo.setDescription(user.getEmail());
        int a = loginInfoMapper.insert(loginInfo);
//        System.out.println(a);
        return new ResponseResult(200, "登录成功");
    }

    //注册
    @Override
    public ResponseResult doRegister(User user, String code, String description, HttpSession session) {

        if (user == null) {
            return new ResponseResult(201, "用户信息必填");
        }
        if (StringUtils.isEmpty(user.getUsername())) {
            return new ResponseResult(202, "用户名必填");
        }
        if (StringUtils.isEmpty(user.getPlainPassword())) {
            return new ResponseResult(203, "密码必填");
        }
        if (StringUtils.isEmpty(user.getEmail())) {
            return new ResponseResult(204, "邮箱必填");
        }
        if (StringUtils.isEmpty(code)) {
            return new ResponseResult(205, "验证码不能为空");
        }
        String EmailCode = (String) session.getAttribute("email1");
//        System.out.println(EmailCode);
        if (!code.equals(EmailCode)) {
            return new ResponseResult(206, "验证码输入错误");
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("email", user.getEmail());
        User user2 = userMapper.selectOne(queryWrapper);
        if (user2 != null) {
            return new ResponseResult(209, "用户邮箱已经存在已经存在");
        }
        //以上代码都不执行  应该执行注册了
        //生成一个盐
        String salt = UUID.randomUUID().toString();
        // 获取原密码  对原密码加密
        String password = user.getPassword();
        //加密后的密码
        String md5Pwd = getMD5Pwd(password, salt);
        //将加密后的密码设置到User对象中
        user.setPassword(md5Pwd);
        user.setSalt(salt);
        String suiji = (int) ((Math.random() * 9 + 1) * 100000) + "";
        user.setId(suiji);
        user.setEmailStatus(0);
        user.setWorkAddress("三楼311");
        user.setAllowNum(25);
        user.setDepartment(1);
        user.setNowNum(0);
        user.setDepartmentType(0);
        user.setTreatmentPrice("3.0");
        Date now = new Date();
        user.setCreateDatetime(now);
//        System.out.println(user);
        //将数据插入到user表中区
        int a = userMapper.insert(user);
        if (a != 1) {
            return new ResponseResult(208, "添加失败");
        }
        //获取选择的角色信息
        //通过role查询查询所选择的角色对象
        Role role1 = roleMapper.findByRole(description);
//        System.out.println("role1："+role1);
        //保存用户与角色信息到中间表
        UserRole userRole = new UserRole();
        userRole.setUid(user.getId());
        userRole.setRoleId(role1.getId());
        String description1 = user.getEmail() + "#" + role1.getRole();
        userRole.setDescription(description1);
        userRole.setRoleStatus(1);
        userRole.setCreateDatetime(now);
        String suiji1 = (int) ((Math.random() * 9 + 1) * 100000) + "";
        userRole.setId(suiji1);
        int b = userRoleMapper.insert(userRole);
        if (b != 1) {
            return new ResponseResult(208, "添加失败");
        }

        return new ResponseResult(200, "添加成功");
    }

    //通过ID查询角色信息
    @Override
    public User findUserInfoByUserId(String id) {
        if (id == null) {
            throw new RuntimeException("会话超时,重新登录");
        }
        User user = userMapper.selectById(id);
        if (user == null) {
            throw new RuntimeException("数据已经被删除");
        }
        return user;
    }

    //更新用户的信息
    @Override
    public ResponseResult updateUserInfo(User user) {

        if (user == null) {
            return new ResponseResult(201, "会话已超时，请重新登陆");
        }
//        System.out.println(user.getUsername());
        if (StringUtils.isEmpty(user.getUsername())) {
            return new ResponseResult(202, "用户名不能为空");
        }
        if (StringUtils.isEmpty(user.getPhone())) {
            return new ResponseResult(204, "电话号码不能为空");
        }
        if (StringUtils.isEmpty(user.getAddress())) {
            return new ResponseResult(205, "通讯地址不能为空");
        }
        if (StringUtils.isEmpty(user.getAddress())) {
            return new ResponseResult(206, "通讯地址不能为空");
        }
        if (StringUtils.isEmpty(user.getPoliticalStatus())) {
            return new ResponseResult(207, "政治面貌不能为空");
        }
//        System.out.println(user);
        int i = userMapper.updateById(user);
//        System.out.println(i);
        if (i != 1) {
            return new ResponseResult(208, "更新失败");
        }
        return new ResponseResult(200, "更新成功");
    }

    //检查原密码
    @Override
    public ResponseResult checkPwd(String oldPassword, HttpSession session) {
        //根据session 获取登录时绑定的用户名
        String username = (String) session.getAttribute("username");
//        System.out.println(username);
        if (username == null) {
            //session在服务端有效时间为 20-30分钟
            return new ResponseResult(201, "会话已超时，请重新登陆");
        }
        //根据用户名查询当前用户信息
        User user = userMapper.findUserByName(username);
        if (user == null) {
            return new ResponseResult(202, "该数据被管理员删除");
        }
        //与user 保存的密码比较
        if (!user.getPlainPassword().equals(oldPassword)) {
            return new ResponseResult(203, "原密码输入错误");
        }
        return new ResponseResult(200, "密码验证通过");
    }

    @Override
    public ResponseResult updatePassword(String oldPassword, String newPassword, String okPassword, HttpSession session) {
//        System.out.println(oldPassword);
//        System.out.println(newPassword);
//        System.out.println(okPassword);
        String username = (String) session.getAttribute("username");
//        System.out.println(username);
        if (username == null) {
            //session在服务端有效时间为 20-30分钟
            return new ResponseResult(201, "会话已超时，请重新登陆");
        }
        if (oldPassword == null || oldPassword == "") {
            return new ResponseResult(202, "原密码不能为空");
        }

        if (StringUtils.isEmpty(newPassword)) {
            return new ResponseResult(203, "新密码不能为空");
        }
        if (StringUtils.isEmpty(okPassword)) {
            return new ResponseResult(204, "确认密码不能为空");
        }
        if (!newPassword.equals(okPassword)) {
            return new ResponseResult(205, "新密码与确认密码不一致");
        }
        User user = userMapper.findUserByName(username);
//        System.out.println(user);
        if (user == null) {
            return new ResponseResult(206, "该数据被管理员删除");
        }
        //对新密码进行加密
        String newSalt = UUID.randomUUID().toString();
        String new5Pwd = getMD5Pwd(newPassword, newSalt);
        //调用持久层跟新的方法
        user.setSalt(newSalt);
        user.setPlainPassword(newPassword);
        user.setPassword(new5Pwd);

        int i = userMapper.updateById(user);
        if (i != 1) {
            return new ResponseResult(207, "修改失败");
        }
        return new ResponseResult(200, "修改成功");
    }

    //通过用户的ID去查询中间表获取角色ID 从而获取对应的角色信息
    @Override
    public ResponseResult findUserRole(HttpSession session) {
        String id = (String) session.getAttribute("id");
        QueryWrapper<UserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("uid", id);
        List<UserRole> UserRoleList = userRoleMapper.selectList(queryWrapper);
        List<Role> list = new ArrayList<>();
        for (UserRole UserRole : UserRoleList) {
            QueryWrapper<Role> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("id", UserRole.getRoleId());
            Role role = roleMapper.selectOne(queryWrapper1);
            list.add(role);
        }
//        System.out.println(list);
        session.setAttribute("UserRole", list);
        Object userRole = session.getAttribute("UserRole");
//        System.out.println(userRole);
        return new ResponseResult(200, list);
    }

    //添加角色
    @Override
    public ResponseResult addUserRole(String description, HttpSession session) {
        //获取登录用户的username
        String username = (String) session.getAttribute("username");
        //查询当前用户对象
        User user = userMapper.findUserByName(username);
        if (user == null) {
            return new ResponseResult(201, "会话已超时，请重新登陆");
        }
        if (description == null) {
            return new ResponseResult(202, "请选择添加的角色");
        }
        //获取选择的角色信息
        //通过role查询查询所选择的角色对象
        Role role1 = roleMapper.findByRole(description);
//        System.out.println("role1："+role1);
        //保存用户与角色信息到中间表
        UserRole userRole = new UserRole();
        //插入当前用户的Id
        userRole.setUid(user.getId());
        userRole.setRoleId(role1.getId());
        String description1 = user.getEmail() + "#" + role1.getRole();
        userRole.setDescription(description1);
        userRole.setRoleStatus(0);
        Date now = new Date();
        userRole.setCreateDatetime(now);
        //生成中间表的ID
        String suiji1 = (int) ((Math.random() * 9 + 1) * 100000) + "";
        userRole.setId(suiji1);
        int b = userRoleMapper.insert(userRole);
//        System.out.println(b);
        if (b != 1) {
            return new ResponseResult(203, "添加失败");
        }
        return new ResponseResult(200, "添加成功");
    }

    //获取审核角色
    @Override
    public String getRoleApply(HttpSession session) {
        //查询所有还未审核的账户
        int i = 1;
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("email_status", 0);
        List<User> list = userMapper.selectList(queryWrapper);
        List<ApplyRspVO> applyRspVO = new ArrayList<>();
        List<UserRole> userRoleList = new ArrayList<>();
        for (User user : list) {
            ApplyRspVO applyRspVO1 = new ApplyRspVO();
            applyRspVO1.setUsername(user.getUsername());
            applyRspVO1.setDateTime(user.getCreateDatetime());
            applyRspVO1.setEmail(user.getEmail());
            QueryWrapper<UserRole> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("uid", user.getId());
            userRoleList = userRoleMapper.selectList(queryWrapper1);
            for (UserRole userRole : userRoleList) {
                QueryWrapper<Role> queryWrapper2 = new QueryWrapper<>();
                queryWrapper2.eq("id", userRole.getRoleId());
                Role role = roleMapper.selectOne(queryWrapper2);
                applyRspVO1.setRole(role.getDescription());
            }
            applyRspVO1.setId(i);
            applyRspVO.add(applyRspVO1);
            i++;
        }
        session.setAttribute("applyRspVO", applyRspVO);
        return "RoleApply";
    }

    //通过审核的话email_state设置为1
    @Override
    public ResponseResult Approved(String username, HttpSession session) {
        User user = userMapper.findUserByName(username);
        Date now = new Date();
        user.setUpdateTime(now);
        user.setEmailStatus(1);
        int i = userMapper.updateById(user);
        if (i != 1) {
            return new ResponseResult(208, "通过失败");
        }
        return new ResponseResult(200, "通过成功");
    }

    //不通过审核的话email_state设置为-1
    @Override
    public ResponseResult NoApproved(String username, HttpSession session) {
        User user = userMapper.findUserByName(username);
        Date now = new Date();
        user.setUpdateTime(now);
        user.setEmailStatus(-1);
        int i = userMapper.updateById(user);
        if (i != 1) {
            return new ResponseResult(208, "操作失败");
        }
        return new ResponseResult(200, "操作成功");
    }

    //检查邮箱是否存在
    @Override
    public ResponseResult checkEmail(String email) {
        if (email == null || email.equals("")) {
            return new ResponseResult(201, "邮箱必填");
        }
        if (!email.endsWith("@qq.com")) {
            return new ResponseResult(203, "仅支持QQ邮箱");
        }

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("email", email);
        User user = userMapper.selectOne(queryWrapper);
        if (user != null) {
            return new ResponseResult(202, "邮箱已存在");
        }

        return new ResponseResult(200, "邮箱可用");
    }

    //检查昵称是否存在
    @Override
    public ResponseResult checkUsername(String username) {
        if (username == null || username.equals("")) {
            return new ResponseResult(201, "注册名必填");
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("Username", username);
        User user = userMapper.selectOne(queryWrapper);
        if (user != null) {
            return new ResponseResult(202, "昵称已存在");
        }

        return new ResponseResult(200, "昵称可用");
    }

    @Override
    public ResponseResult findUserLoginInfo(HttpSession session, @RequestParam(defaultValue = "1", value = "pageNum") Integer pageNum) {
        String id = (String) session.getAttribute("id");
        if (id == null) {
            return new ResponseResult(200, "会话超时，请重新登录");
        }
        QueryWrapper<LoginInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", id);
        PageHelper.startPage(pageNum, 8);
        List<LoginInfo> list = loginInfoMapper.selectList(queryWrapper);
//        System.out.println(list);
        //预置分页条件进行查询  第一个参数当前页码   第二参数是每页显示几条数据
        // PageHelper.startPage(2,2); 或者
        PageInfo<LoginInfo> pageInfo = new PageInfo<LoginInfo>(list);
//        System.out.println("存进分页里面"+pageInfo);
        /*  return  pageInfo.getList();//返回当前页数据封装到集合中返回*/
        session.setAttribute("pageInfo", pageInfo);
        return new ResponseResult(200, list);
    }

    //判断电话号码是否正确
    @Override
    public ResponseResult checkPhone(String phone,HttpSession session) {
        PhoneVerification phoneVerification = new PhoneVerification();
        boolean phoneLegal = phoneVerification.isPhoneLegal(phone);
        if (phoneLegal == false) {
            return new ResponseResult(202, "电话号码输入格式错误");
        } else {
            return new ResponseResult(200, "电话号码格式正确");

        }
    }
            //封装一个方法 对密码进行加密
    private String getMD5Pwd(String password, String salt) {
        String md5Pwd = password + salt;
        //加密
        for (int i = 0; i < 10; i++) {
            md5Pwd = DigestUtils.md5DigestAsHex(md5Pwd.getBytes());
        }
        return md5Pwd;
    }


}
